home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
dev
/
gcc
/
bmake15.lzh
/
fncall.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-23
|
16KB
|
743 lines
/* fncall.c
* (c) Copyright 1991 by Ben Eng, All Rights Reserved
*
*/
#include <clib/exec_protos.h>
#include <ctype.h>
#include <scdir.h>
#include "make.h"
#include "depend.h"
#if FNCALLS
/* function calls (mac, string)
*
* The string parameter is the rest of the arguments passed to the
* function call. string is modifiable in fncalls because it is
* actually contained within the macroname array[] which isn't
* really used again after the fncall returns.
*
* returns 0 if successful, 1 if error
* with side effect: mac->expansion = strdup( result_string );
*
*/
static char argument_missing[] = "argument missing: %s %s\n";
static char error_no_memory[] = "error: no memory\n";
static int
do_basename( struct macro *mac, char *string, how_basename )
{
char *filelist = NULL;
char *out, *text, *cptr;
int len = 0;
char word[ MAXPATHNAME ];
filelist = (char *)calloc( Param.MaxLine, 1 );
if( !filelist ) {
logfile( error_no_memory );
return( 1 );
}
out = filelist;
text = string;
while( len < Param.MaxLine ) {
text = parse_str( word, text, sizeof(word));
if( !*word )
break; /* no more words in text */
cptr = strrchr( word, '.' );
if( how_basename ) { /* take the basename */
if( cptr && basename(word) <= cptr ) {
*cptr = (char)0; /* truncate the word at the `.' */
}
}
else { /* take the suffix */
if( cptr && basename(word) <= cptr ) {
shift_string_left( word, (int)(cptr - word));
}
}
len += strlen( word );
if( len + 1 < Param.MaxLine ) {
if( out != filelist ) {
*out++ = ' ';
len++;
}
strcpy( out, word );
out = filelist + len;
}
else break;
} /* while */
*out = (char)0;
if( len > 0 )
mac->expansion = strdup( filelist );
free( filelist );
return( 0 );
}
static int
fn_basename( struct macro *mac, char *string )
{
return( do_basename( mac, string, 1 ));
}
static int
fn_suffix( struct macro *mac, char *string )
{
return( do_basename( mac, string, 0 ));
}
static int
do_addfix( struct macro *mac, char *string, int how_fix )
{
char *filelist = NULL;
char *suf, *str = string;
filelist = (char *)calloc( Param.MaxLine, 1 );
if( !filelist ) {
logfile( error_no_memory );
return( 1 );
}
while( isspace( *str )) str++;
suf = str;
while( *str && *str != ',' && str[-1] != '\\' ) str++;
if( *suf != ',' && *str == ',' && str[-1] != '\\' ) {
char *out, *text, *cptr;
int suflen, len = 0;
char word[ MAXPATHNAME ];
*str++ = (char)0; /* null terminate the suffix */
suflen = strlen( suf );
out = filelist;
text = str;
while( len < Param.MaxLine ) {
text = parse_str( word, text, sizeof(word));
if( !*word )
break; /* no more words in text */
if( (strlen( word )+suflen) < sizeof(word)) {
if( how_fix ) /* append the suffix */
strcat( word, suf );
else { /* prepend the prefix */
len += strlen( suf );
if( len + 1 < Param.MaxLine ) {
if( out != filelist ) {
*out++ = ' ';
len++;
}
strcpy( out, suf );
out = filelist + len;
}
}
}
len += strlen( word );
if( len + 1 < Param.MaxLine ) {
if( out != filelist & how_fix ) {
*out++ = ' ';
len++;
}
strcpy( out, word );
out = filelist + len;
}
else break;
} /* while */
*out = (char)0;
if( len > 0 )
mac->expansion = strdup( filelist );
}
free( filelist );
return( 0 );
}
static int
fn_addprefix( struct macro *mac, char *string )
{
return( do_addfix( mac, string, 0 ));
}
static int
fn_addsuffix( struct macro *mac, char *string )
{
return( do_addfix( mac, string, 1 ));
}
static int
do_dir( struct macro *mac, char *string, int how_dir )
{
char *filelist = NULL;
char *str = string;
char *out, *text, *cptr;
int len = 0;
char word[ MAXPATHNAME ];
filelist = (char *)calloc( Param.MaxLine, 1 );
if( !filelist ) {
logfile( error_no_memory );
return( 1 );
}
while( isspace( *str )) str++;
out = filelist;
text = str;
while( len < Param.MaxLine ) {
text = parse_str( word, text, sizeof(word));
if( !*word )
break; /* no more words in text */
cptr = basename( word );
if( how_dir ) { /* keep only the directory part */
*cptr = (char)0;
}
else { /* prepend the prefix */
shift_string_left( word, (int)(cptr - word));
}
len += strlen( word );
if( len + 1 < Param.MaxLine ) {
if( out != filelist ) {
*out++ = ' ';
len++;
}
strcpy( out, word );
out = filelist + len;
}
else break;
} /* while */
*out = (char)0;
if( len > 0 )
mac->expansion = strdup( filelist );
free( filelist );
return( 0 );
}
static int
fn_dir( struct macro *mac, char *string )
{
return( do_dir( mac, string, 1 ));
}
static int
fn_notdir( struct macro *mac, char *string )
{
return( do_dir( mac, string, 0 ));
}
static int
do_filter( struct macro *mac, char *string, int how_filter )
{
char *str = string;
char *pat;
int len;
while( isspace( *str )) str++;
pat = str;
while( *str && *str != ',' && str[-1] != '\\' ) str++;
if( *pat != ',' && *str == ',' && str[-1] != '\\' ) {
char word[ 80 ];
char *text, *out;
*str++ = (char)0;
if( !( mac->expansion = strdup( str )))
return( 0 ); /* no mem */
out = mac->expansion;
for( text = out;; ) {
text = parse_str( word, text, sizeof(word));
if( !*word )
break; /* no more words in text */
if( how_filter ) {
if( pattern_match( pat, word )) {
out = text + 1;
}
else { /* no match remove it */
while( isspace( *text )) text++;
shift_string_left( out, (int)(text - out));
text = out;
}
}
else {
if( pattern_match( pat, word )) {
while( isspace( *text )) text++;
shift_string_left( out, (int)(text - out));
text = out;
}
else { /* no match remove it */
out = text + 1;
}
}
} /* for */
*out = (char)0;
return( 0 );
}
logprintf( argument_missing, "filter", string );
return( 1 );
}
static int
fn_filter( struct macro *mac, char *string )
{
return( do_filter( mac, string, 1 ));
}
static int
fn_filter_out( struct macro *mac, char *string )
{
return( do_filter( mac, string, 0 ));
}
static int
fn_findstring( struct macro *mac, char *string )
{
char *find, *in, *str = string;
int len;
while( isspace( *str )) str++;
find = str;
while( *str && *str != ',' && str[-1] != '\\' ) str++;
if( *find != ',' && *str == ',' && str[-1] != '\\' ) {
*str++ = (char)0;
in = str;
while( *str ) str++; /* find end string */
len = strlen( find );
str -= len; /* str marks the end of searching */
while( in <= str ) {
if( !strnicmp( find, in, len )) { /* found */
mac->expansion = strdup( find );
break;
}
in++;
}
}
else {
logprintf( argument_missing, "findstring", string );
return( 1 );
}
return( 0 );
}
static int
fn_getenv( struct macro *mac, char *string )
{
char *evalue;
while( isspace( *string )) string++;
evalue = getenv( string );
if( evalue && *evalue )
mac->expansion = strdup( evalue );
return( 0 );
}
static int
fn_join( struct macro *mac, char *string )
{
char *filelist = NULL;
char *str = string;
char *text1, *text2;
filelist = (char *)calloc( Param.MaxLine, 1 );
if( !filelist ) {
logfile( error_no_memory );
return( 1 );
}
while( isspace( *str )) str++;
text1 = str;
while( *str && *str != ',' && str[-1] != '\\' ) str++;
if( *text1 != ',' && *str == ',' && str[-1] != '\\' ) {
char *out;
int len = 0;
char word1[ MAXPATHNAME ], word2[ MAXPATHNAME ];
*str++ = (char)0; /* null terminate the suffix */
out = filelist;
text2 = str;
*word1 = *word2 = ' '; /* dummy for first iteration */
while( len < Param.MaxLine ) {
if( *word1 )
text1 = parse_str( word1, text1, sizeof(word1));
if( *word2 )
text2 = parse_str( word2, text2, sizeof(word2));
if( !*word1 && !*word2 )
break; /* no more words */
len += strlen( word1 ) + strlen( word2 );
if( len + 1 < Param.MaxLine ) {
if( out != filelist ) {
*out++ = ' ';
len++;
}
strcpy( out, word1 );
strcat( out, word2 );
out = filelist + len;
}
else break;
} /* while */
*out = (char)0;
if( len > 0 )
mac->expansion = strdup( filelist );
}
if( filelist )
free( filelist );
return( 0 );
}
static int
fn_patsubst( struct macro *mac, char *string )
{
char *str = string;
char *from, *to, *text;
while( isspace( *str )) str++;
from = str;
while( *str && *str != ',' && str[-1] != '\\' ) str++;
if( *from != ',' && *str == ',' && str[-1] != '\\' ) {
*str++ = (char)0;
to = str;
while( *str && *str != ',' && str[-1] != '\\' ) str++;
if( *to != ',' && *str == ',' && str[-1] != '\\' && str[ 1 ] ) {
char *expansion = NULL, *out;
int len = 0;
*str++ = (char)0;
while( *str && isspace( *str )) str++;
text = str;
out = expansion = (char *)malloc( Param.MaxLine );
if( !expansion ) {
logfile( error_no_memory );
return( 1 );
}
while( *str ) {
while( *str && !isspace( *str )) str++;
if( !*str && str == text )
break;
if( *str )
*str++ = (char)0;
if( len + (int)(str - text) < Param.MaxLine ) {
if( out > expansion ) {
*out++ = ' ';
len++;
}
if( pattern_match( from, text )) {
/* needs to do bounds checking to prevent */
/* overflowing of the expansion string! */
/* neglected for now - user discretion advised */
if( map_to_pattern( out, from, to, text ))
break;
}
else strcpy( out, text );
}
len += strlen( out );
out = expansion + len;
while( *str && isspace( *str )) str++;
text = str;
}
*out = (char)0;
if( *expansion )
mac->expansion = strdup( expansion );
free( expansion );
return( 0 );
}
}
logprintf( argument_missing, "patsubst", string );
return( 1 );
}
static int
sortcomp( char **s1, char **s2 )
{
return( stricmp( *s1, *s2 ));
}
static int
fn_sort( struct macro *mac, char *string )
{
int i, nel;
char **array = NULL;
char *expansion = NULL;
char *out, *str = string;
while( isspace( *str )) str++;
nel = count_args( str );
array = (char **)calloc( sizeof(char *), nel );
expansion = (char *)malloc( Param.MaxLine );
if( !array || !expansion ) {
logfile( error_no_memory );
if( array )
free( array );
if( expansion )
free( expansion );
return( 1 );
}
for( i = 0; i < nel && *str; i++ ) {
while( isspace( *str ))
str++;
if( *str )
array[ i ] = str++;
while( !isspace( *str ) && *str )
str++;
if( isspace( *str ))
*str++ = (char)0;
}
qsort( array, nel, sizeof(char *), sortcomp );
out = expansion;
for( i = 0; i < nel; i++ ) {
if( i )
*out++ = ' ';
strcpy( out, array[ i ] );
out += strlen( out );
}
free( array );
mac->expansion = strdup( expansion );
free( expansion );
return( 0 );
}
static int
fn_strip( struct macro *mac, char *str )
{
while( isspace( *str )) str++;
if( *str && (mac->expansion = strdup( str ))) {
register char *d = mac->expansion;
register char *s = mac->expansion;
while( *s ) {
*d++ = *s;
if( isspace(*s))
while( isspace( *s)) s++;
else
s++;
}
if( isspace( *d )) {
while( isspace( *d ) && d > mac->expansion )
d--;
d++;
}
*d = (char)0;
}
return( 0 );
}
static int
fn_subst( struct macro *mac, char *string )
{
char *str = string;
char *from, *to, *text, *out;
char *expansion = NULL;
int fromlen, tolen;
while( isspace( *str )) str++;
from = str;
while( *str && *str != ',' && str[-1] != '\\' ) str++;
if( *from != ',' && *str == ',' && str[-1] != '\\' ) {
*str++ = (char)0;
to = str;
while( *str && *str != ',' && str[-1] != '\\' )
str++;
if( *to != ',' && *str == ',' && str[-1] != '\\' && str[ 1 ] ) {
*str++ = (char)0;
text = str;
fromlen = strlen( from );
tolen = strlen( to );
while( *str ) str++; /* find end string */
str -= fromlen;
out = expansion = (char *)malloc( Param.MaxLine );
if( !expansion ) {
logfile( error_no_memory );
return( 1 );
}
while( text <= str ) {
if( !strnicmp( from, text, fromlen )) { /* found */
if( (int)(out - expansion) + tolen < Param.MaxLine ) {
strcpy( out, to );
out += tolen;
}
else break;
text += fromlen;
}
else if((int)(out - expansion) + tolen < Param.MaxLine ) {
*out++ = *text++;
}
else break;
}
*out = (char)0;
if( *expansion )
mac->expansion = strdup( expansion );
free( expansion );
return( 0 );
}
}
logprintf( argument_missing, "subst", string );
return( 1 );
}
static int
fn_wildcard( struct macro *mac, char *string )
{
char *filelist = NULL;
char *pat = string;
filelist = (char *)calloc( Param.MaxLine, 1 );
if( !filelist ) {
logfile( error_no_memory );
return( 1 );
}
while( isspace( *pat )) pat++;
if( *pat ) {
char *out = filelist;
char *fn;
int len = 0;
while( len < Param.MaxLine ) {
if( !(fn = scdir( pat )))
break; /* no more */
if( out != filelist ) {
*out++ = ' ';
len++;
}
len += strlen( fn );
if( len < Param.MaxLine ) {
strcpy( out, fn );
out = filelist + len;
}
}
if( len > 0 )
mac->expansion = strdup( filelist );
scdir_abort();
}
free( filelist );
return( 0 );
}
int
do_word( struct macro *mac, char *string, int word )
{
char *begin, *end;
if( begin = find_word( string, word )) {
end = begin;
while( *end && !isspace( *end )) end++;
*end = (char)0; /* null terminate past the end of word */
mac->expansion = strdup( begin );
}
return( 0 );
}
static int
fn_firstword( struct macro *mac, char *string )
{
while( isspace( *string )) string++;
return( do_word( mac, string, 1 ));
}
static int
fn_word( struct macro *mac, char *string )
{
char *comma;
int word;
while( isspace( *string )) string++;
if( *string && (comma = find_token( string, ',' ))) {
*comma = (char)0;
word = atoi( string );
/* else word not found */
return( do_word( mac, comma + 1, word ));
}
logprintf( argument_missing, "word", string );
return( 1 );
}
static int
fn_words( struct macro *mac, char *string )
{
char buf[ 20 ];
sprintf( buf, "%d", count_args( string ));
mac->expansion = strdup( buf );
return( 0 );
}
static int
fn_notimp( struct macro *mac, char *string )
{
logfile( "Function call not implemented\n" );
return( 1 );
}
/*************************************************************************/
/* sorted array for binary search */
#define MAX_FNCALL 22
static struct fncall fncarray[ MAX_FNCALL ] = {
"addprefix", fn_addprefix,
"addsuffix", fn_addsuffix,
"basename", fn_basename,
"dir", fn_dir,
"filter", fn_filter,
"filter-out", fn_filter_out,
"findstring", fn_findstring,
"firstword", fn_firstword,
"foreach", fn_notimp,
"getenv", fn_getenv,
"join", fn_join,
"notdir", fn_notdir,
"origin", fn_notimp,
"patsubst", fn_patsubst,
"shell", fn_notimp,
"sort", fn_sort,
"strip", fn_strip,
"subst", fn_subst,
"suffix", fn_suffix,
"wildcard", fn_wildcard,
"word", fn_word,
"words", fn_words
};
/* binary search to find the function */
struct fncall *
find_fncall( char *name )
{
register struct fncall *array = fncarray;
int first = 0;
int last = MAX_FNCALL - 1;
int mid;
int diff;
/* binary search */
while( first <= last ) {
mid = (first+last) / 2;
diff = stricmp( name, array[ mid ].name );
if( !diff )
return( &array[ mid ] ); /* found */
if( first == last )
break; /* not found */
if( diff < 0 )
last = mid - 1;
else
first = mid + 1;
}
return( NULL ); /* not found */
}
#else
/* No FNCALLS */
struct fncall *
find_fncall( char *name )
{
return( NULL ); /* not found */
}
#endif